package com.op.crm.persist.dao.impl;

import java.sql.SQLException;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.orm.hibernate3.HibernateCallback;

import com.op.crm.persist.dao.AbstractBaseDao;
import com.op.crm.persist.dao.SecurityDao;
import com.op.crm.persist.model.Action;
import com.op.crm.persist.model.Group;
import com.op.crm.persist.model.Role;
import com.op.crm.persist.model.User;

public class SecurityDaoImpl extends AbstractBaseDao<User, User> implements SecurityDao{

	@Override
	public User getUser(String username) throws Exception {
		User user = this.getHibernateTemplate().get(User.class, username);
		return user;
	}

	@Override
	public void saveUser(User user) throws Exception {
		this.getHibernateTemplate().save(user);
	}

	@Override
	public void saveAction(Action action) throws Exception {
		this.getHibernateTemplate().save(action);
	}

	@Override
	public void saveGroup(Group group) throws Exception {
		this.getHibernateTemplate().save(group);
	}

	@Override
	public void saveRole(Role role) throws Exception {
		this.getHibernateTemplate().save(role);
	}

	@Override
	public Action getAction(String actionId) throws Exception {
		return this.getHibernateTemplate().get(Action.class, actionId);
	}

	@Override
	public Role getRole(String roleId) throws Exception {
		return this.getHibernateTemplate().get(Role.class, roleId);
	}

	@Override
	public Group getGroup(String groupId) throws Exception {
		return this.getHibernateTemplate().get(Group.class, groupId);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Action> selectActions() throws Exception {
		return (List<Action>)this.getHibernateTemplate().find("select distinct a from Action a");
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Action> selectActionByIds(final List<String> idList)
			throws Exception {
		final String hql = "select distinct a from Action a left join fetch a.roles where a.actionId in (:pList)";
		List<Action> results = this.getHibernateTemplate().executeFind(new HibernateCallback<List<Action>>() {

			@Override
			public List<Action> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setParameterList("pList", idList);
				return query.list();
			}
			
		});
		return results;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Role> selectRoleByIds(final List<String> idList)
			throws Exception {
		final String hql = "select distinct r from Role r left join fetch r.actions where r.roleId in (:pList)";
		List<Role> results = this.getHibernateTemplate().executeFind(new HibernateCallback<List<Role>>() {

			@Override
			public List<Role> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setParameterList("pList", idList);
				return query.list();
			}
			
		});
		return results;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<Group> selectGroupByIds(final List<String> idList)
			throws Exception {
		final String hql = "select distinct g from Group g where g.groupId in (:pList)";
		List<Group> results = this.getHibernateTemplate().executeFind(new HibernateCallback<List<Group>>() {

			@Override
			public List<Group> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setParameterList("pList", idList);
				return query.list();
			}
			
		});
		return results;
	}
	
	@SuppressWarnings("unchecked")
	@Override
	public List<User> selectUserByIds(final List<String> idList)
			throws Exception {
		final String hql = "select distinct u from User u where u.userId in (:pList)";
		List<User> results = this.getHibernateTemplate().executeFind(new HibernateCallback<List<User>>() {

			@Override
			public List<User> doInHibernate(Session session)
					throws HibernateException, SQLException {
				Query query = session.createQuery(hql);
				query.setParameterList("pList", idList);
				return query.list();
			}
			
		});
		return results;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Role> selectRoles() throws Exception {
		List<Role> results = (List<Role>)this.getHibernateTemplate().find("select distinct r from Role r left join fetch r.actions");
		return results;
	}

	@Override
	public void updateAction(Action action) throws Exception {
		this.getHibernateTemplate().update(action);
	}

	@Override
	public void updateGroup(Group group) throws Exception {
		this.getHibernateTemplate().update(group);
	}

	@Override
	public void updateRole(Role role) throws Exception {
		this.getHibernateTemplate().update(role);
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<Action> selectActionNotIn(final List<Action> actions) throws Exception {
		final String hql = "select distinct a from Action a where a not in (:pList)";
		return this.getHibernateTemplate().executeFind(new HibernateCallback<List<Action>>() {

			@Override
			public List<Action> doInHibernate(Session session) throws HibernateException,
					SQLException {
				Query query = session.createQuery(hql);
				query.setParameterList("pList", actions);
				
				return (List<Action>)query.list();
			}
			
		});
	}

	@Override
	public void deleteAction(Action action) throws Exception {
		for (Role r : action.getRoles()) {
			r.getActions().remove(action);
		}
		this.getHibernateTemplate().delete(action);
	}

}
